package com.leehom.arch.obs.metrics.exporter;

import java.util.Collections;
import java.util.SortedMap;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.codahale.metrics.Counter;
import com.codahale.metrics.Gauge;
import com.codahale.metrics.Histogram;
import com.codahale.metrics.Meter;
import com.codahale.metrics.MetricAttribute;
import com.codahale.metrics.MetricFilter;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.ScheduledReporter;
import com.codahale.metrics.Timer;
import com.leehom.arch.obs.metrics.exporter.prometheus.DropWizardPrometheusExporter;
import com.leehom.arch.obs.metrics.exporter.prometheus.TagExtrator;

import io.prometheus.client.exporter.PushGateway;

/**
 * @类名: NopSchedulerReporter
 * @说明: 啥也不做报告器，相当于屏蔽
 *
 * @author   leehom
 * @Date	 2021年12月2日 下午5:24:34
 * 修改记录：
 *
 * @see 	 
 */
public class NopSchedulerReporter extends ScheduledReporter {

    /**
     * A builder for {@link NopSchedulerReporter} instances. Defaults to not using a prefix, and
     * not filtering metrics.
     */
    public static class Builder {

        private final MetricRegistry registry;
        private String job;
        private String url;
        private TagExtrator tagExtractor;
        private MetricFilter filter;
        private ScheduledExecutorService executor;
        private boolean shutdownExecutorOnStop;

        private Builder(MetricRegistry registry) {
            this.registry = registry;
            this.url = null;
            this.filter = MetricFilter.ALL;
            this.executor = null;
            this.shutdownExecutorOnStop = true;
        }

        /**
         * Specifies whether or not, the executor (used for reporting) will be stopped with same time with reporter.
         * Default value is true.
         * Setting this parameter to false, has the sense in combining with providing external managed executor via {@link #scheduleOn(ScheduledExecutorService)}.
         *
         * @param shutdownExecutorOnStop if true, then executor will be stopped in same time with this reporter
         * @return {@code this}
         */
        public Builder shutdownExecutorOnStop(boolean shutdownExecutorOnStop) {
            this.shutdownExecutorOnStop = shutdownExecutorOnStop;
            return this;
        }

        /**
         * Specifies the executor to use while scheduling reporting of metrics.
         * Default value is null.
         * Null value leads to executor will be auto created on start.
         *
         * @param executor the executor to use while scheduling reporting of metrics.
         * @return {@code this}
         */
        public Builder scheduleOn(ScheduledExecutorService executor) {
            this.executor = executor;
            return this;
        }
        
        public Builder url(String url) {
            this.url = url;
            return this;
        }

        public Builder job(String job) {
            this.job = job;
            return this;
        }
        
        public Builder tag(TagExtrator extractor) {
            this.tagExtractor = extractor;
            return this;
        }

        /**
         * Only report metrics which match the given filter.
         *
         * @param filter a {@link MetricFilter}
         * @return {@code this}
         */
        public Builder filter(MetricFilter filter) {
            this.filter = filter;
            return this;
        }

        /**
         * Builds a {@link NopSchedulerReporter} with the given properties, sending metrics using the
         * given {@link MetricsSender}.
         *
         * @param prometheus a {@link MetricsSender}
         * @return a {@link NopSchedulerReporter}
         */
        public NopSchedulerReporter build() {
            return new NopSchedulerReporter(registry,
            							job,
                                        url,
                                        tagExtractor,
                                        filter,
                                        executor,
                                        shutdownExecutorOnStop);
        }

    }

    private static final TimeUnit DURATION_UNIT = TimeUnit.MILLISECONDS;
    private static final TimeUnit RATE_UNIT = TimeUnit.SECONDS;

    private static final Logger LOGGER = LoggerFactory.getLogger(NopSchedulerReporter.class);

    private String job;
    private PushGateway pg; 
    private DropWizardPrometheusExporter metricExproter = new DropWizardPrometheusExporter();
    private TagExtrator tagExtractor;
    
    /**
     * Creates a new {@link NopSchedulerReporter} instance.
     *
     * @param registry               the {@link MetricRegistry} containing the metrics this
     *                               reporter will report
     * @param sender               the {@link MetricsSender} which is responsible for sending metrics to a Carbon server
     *                               via a transport protocol
     * @param prefix                 the prefix of all metric names (may be null)
     * @param filter                 the filter for which metrics to report
     * @param executor               the executor to use while scheduling reporting of metrics (may be null).
     * @param shutdownExecutorOnStop if true, then executor will be stopped in same time with this reporter
     */
    protected NopSchedulerReporter(MetricRegistry registry, String job, String url, TagExtrator tagExtractor, 
    				MetricFilter filter, ScheduledExecutorService executor, boolean shutdownExecutorOnStop) {
        super(registry, "prometheus-reporter", filter, RATE_UNIT, DURATION_UNIT, executor, shutdownExecutorOnStop, Collections.<MetricAttribute>emptySet());
        this.job = job;
        pg = new PushGateway(url);
        this.tagExtractor = tagExtractor;
    }

    
    @Override
    @SuppressWarnings("rawtypes")
    public void report(SortedMap<String, Gauge> gauges, SortedMap<String, Counter> counters, SortedMap<String, Histogram> histograms, SortedMap<String, Meter> meters, SortedMap<String, Timer> timers) {
    	// do nothing
    }
    
    /**
     * Returns a new {@link Builder} for {@link NopSchedulerReporter}.
     *
     * @param registry the registry to report
     * @return a {@link Builder} instance for a {@link NopSchedulerReporter}
     */
    public static Builder forRegistry(MetricRegistry registry) {
        return new Builder(registry);
    }


	@Override
	public void start(long period, TimeUnit unit) {
		// 不启动
	}


	@Override
	public synchronized void start(long initialDelay, long period, TimeUnit unit) {
		// 不启动
	}

}
